package com.my.myTradeData;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.eclipse.jetty.util.BlockingArrayQueue;
import org.zeromq.ZMQ;

import com.my.myTradeData.DataSource.Dictionary;
import com.my.myTradeData.DataSource.Sina;
import com.my.stock.core.KLine;

public class ATRTrade implements Runnable {

	// public BlockingQueue<TickData> tickQueue = new
	// ArrayBlockingQueue<TickData>(
	// 1000 * 1024);

	private static ZMQ.Context context = ZMQ.context(1);
	private static ZMQ.Socket s = context.socket(ZMQ.REQ);
	private static BlockingArrayQueue<String> q = new BlockingArrayQueue<String>(1024 * 10);

	private static String BASE_PATH = "c:\\1\\";

	private List<KLine> klineList = new ArrayList<KLine>();

	private boolean hasPostion = false;

	private boolean hasShortPostion = false;

	private double currentSTD = 0;

	public String code = "";

	private List<Double> currentDateList = new ArrayList<Double>();

	private double currentAtr = 0;

	private int currentDatePeriod = 0;

	private boolean lastTick = true;

	private static Map<String, Double> std2Map = new HashMap<String, Double>();
	private static Map<String, Double> stdk2Map = new HashMap<String, Double>();
	private static Map<String, Double> stds2Map = new HashMap<String, Double>();
	private static Map<String, Double> stdsk2Map = new HashMap<String, Double>();

	private static Map<String, Double> shortAtrMap = new HashMap<String, Double>();
	private static Map<String, Double> longAtrMap = new HashMap<String, Double>();

	public static void main(String[] args) throws InterruptedException, IOException, ParseException {

		shortAtrMap.put("SF", 3.0);
		longAtrMap.put("SF", 3.0);
		shortAtrMap.put("SM", 3.0);
		longAtrMap.put("SM", 3.0);
		
		
		
		shortAtrMap.put("bu", 2.7);
		longAtrMap.put("bu", 3.6);
		shortAtrMap.put("l", 3.6);
		longAtrMap.put("l", 3.6);
		shortAtrMap.put("TA", 2.9);
		shortAtrMap.put("J", 4.0);
		shortAtrMap.put("a", 3.8);
		shortAtrMap.put("p", 2.8);
		shortAtrMap.put("c", 3.4);
		longAtrMap.put("c", 3.6);
		shortAtrMap.put("rb", 3.9);
		shortAtrMap.put("OI", 2.8);
		longAtrMap.put("OI", 3.6);
		shortAtrMap.put("pb", 3.9);
		shortAtrMap.put("b", 2.4);
		shortAtrMap.put("RM", 2.7);
		shortAtrMap.put("m", 3.7);
		longAtrMap.put("ru", 3.9);
		longAtrMap.put("v", 3.3);
		longAtrMap.put("pp", 3.3);
		longAtrMap.put("SR", 3.4);
		longAtrMap.put("CF", 4.0);
		longAtrMap.put("cs", 3.9);
		longAtrMap.put("i", 2.8);
		longAtrMap.put("sn", 3.8);

		std2Map.put("SF", 8.67);
		std2Map.put("SM", 4.06);
		std2Map.put("bu", 6.5);
		std2Map.put("v", 2.57);
		std2Map.put("CF", 14.23);
		std2Map.put("al", 4.64);
		std2Map.put("OI", 15.18);
		std2Map.put("sn", 11.08);
		std2Map.put("pb", 10.76);
		std2Map.put("b", 13.4);

		stds2Map.put("ZC", 11.95);
		stds2Map.put("j", 6.86);
		stds2Map.put("OI", 5.73);
		stds2Map.put("sn", 9.01);
		stds2Map.put("pb", 10.26);
		stds2Map.put("b", 19.56);
		stds2Map.put("RM", 2.08);

		stdk2Map.put("SF", 13.11);
		stdk2Map.put("SM", 13.74);
		stdk2Map.put("ru", 11.95);
		stdk2Map.put("l", 7.1);
		stdk2Map.put("v", 14.46);
		stdk2Map.put("a", 8.21);
		stdk2Map.put("p", 3.54);
		stdk2Map.put("CF", 16.74);
		stdk2Map.put("al", 24.7);
		stdk2Map.put("OI", 10.14);
		stdk2Map.put("sn", 6.88);
		stdk2Map.put("pb", 11.33);

		stdsk2Map.put("sn", 6.08);
		stdsk2Map.put("pb", 8.04);

		List<String> codeList = new ArrayList<String>();

		codeList.add("SF005");
		codeList.add("SM005");
		codeList.add("bu2005");
		codeList.add("l2005");
		codeList.add("TA005");
		codeList.add("J005");
		codeList.add("a2005");
		codeList.add("p2005");
		codeList.add("c2005");
		codeList.add("rb2005");
		codeList.add("OI005");
//		codeList.add("pb2005");
		codeList.add("b2005");
//		codeList.add("RM005");
		codeList.add("ru2005");
		codeList.add("m2005");
		codeList.add("v2005");
		codeList.add("pp2005");
		codeList.add("SR005");
		codeList.add("CF005");
		codeList.add("cs2005");
		codeList.add("i2005");
		codeList.add("sn2005");

		for (String code : codeList) {
			ATRTrade a = new ATRTrade();
			a.code = code;

			(new Thread(a)).start();

		}

		s.connect("tcp://127.0.0.1:5557");
		// q.offer("buy,au1905,1,2,3\0");

		while (true) {
			String str = q.take();
			s.send(str.getBytes());
			byte[] response = s.recv();
			System.out.print(new String(response));
		}

	}

	public void initATR() throws IOException {
		File f = new File(BASE_PATH + code + ".txt");

		if (!f.exists()) {
			List<DayData> l = Sina.get15mData(code);

			// if(l.size()<120){
			// System.out.println(code);
			// return;
			// }

			for (int i = 0; i < 100; i++) {
				KLine k = new KLine();
				k.setOpen(l.get(i).getOpen());
				k.setClose(l.get(i).getClose());
				k.setHigh(l.get(i).getHigh());
				k.setLow(l.get(i).getLow());

				SimpleDateFormat myFmt1 = new SimpleDateFormat("yyyyMMdd hh:mm:ss SSS");

				k.setDate(myFmt1.format(l.get(i).getDataDate()));

				if (k.getOpen() == k.getClose() && k.getLow() == k.getHigh() && k.getOpen() == k.getHigh()) {

				} else {

					if (l.get(i).getDataDate().after(new Date())) {

					} else {
						klineList.add(k);
					}

				}

			}

			String writeStr = "";
			System.out.println(code);
			for (int i = 0; i < klineList.size() - 1; i++) {

				klineList.get(i).setTr(TechnicalAnalysisIndicators.getTr(klineList.get(i), klineList.get(i + 1)));
				JSONObject json = JSONObject.fromObject(klineList.get(i));// 将java对象转换为json对象
				String str = json.toString();
				writeStr = writeStr + str + "\r\n";

			}
			JavaFile.writefile(BASE_PATH + code + ".txt", writeStr);

		} else {
			List<String> slist = JavaFile.readfile(BASE_PATH + code + ".txt");
			for (String s : slist) {
				if (s.length() > 0) {
					JSONObject json = JSONObject.fromObject(s);// 将java对象转换为json对象
					KLine kline = (KLine) JSONObject.toBean(json, KLine.class);
					klineList.add(kline);
				}
			}
		}
	}

	private KLine currentKLine = new KLine();

	public void main() throws InterruptedException, IOException {

		initATR();
		currentAtr = TechnicalAnalysisIndicators.getAtr(klineList);

		double[] stdd = new double[100];

		for (int i = 0; i < klineList.size(); i++) {
			stdd[i] = klineList.get(i).getTr();
		}
		currentSTD = MathUtil.getStandardDiviation(stdd);
		// TickData d = new TickData();
		// d.setAveragePrice(50011);
		// d.setBuyPrice(50200);
		// d.setSellPrice(50300);
		// d.setTickDate(new Date());
		//

		// tickQueue.offer(d);
		while (true) {
			try {

				JavaFile.writefile(BASE_PATH + code + "_Tick.txt", sg + "\r\n", true);
				// System.out.println(sg);

				// System.out.println(TechnicalAnalysisIndicators.getTr(currentKLine,
				// klineList.get(0))+" "+(currentAtr + 2 * currentSTD));

				if (longAtrMap.get(code.replaceAll("[\\d]", "")) != null && !hasPostion
						&& currentKLine.getClose() < klineList.get(0).getClose()
						&& currentKLine.getTr() > currentAtr * longAtrMap.get(code.replaceAll("[\\d]", ""))) {

					if (currentDatePeriod >= 1 && hasPostion == false) {
						hasPostion = true;
						sendOrder(true);
					}
					{

						// 开盘策略
					}

				}

				if (shortAtrMap.get(code.replaceAll("[\\d]", "")) != null && !hasShortPostion
						&& currentKLine.getClose() > klineList.get(0).getClose()
						&& currentKLine.getTr() > currentAtr * shortAtrMap.get(code.replaceAll("[\\d]", ""))) {

					if (currentDatePeriod >= 1 && hasShortPostion == false) {
						hasShortPostion = true;
						sendOrder(false);
					}
					{
					}

				}

				if (closeToLastTick(t.getT())) {
					if (currentKLine.getTr() < currentAtr) {
						// hasPostion = false;
						if (hasPostion || hasShortPostion) {
							if (hasPostion) {
								sendStopPostion(true);
							}
							if (hasShortPostion) {
								sendStopPostion(false);
							}

						}

					}
				}

				SimpleDateFormat myFmt = new SimpleDateFormat("yyyyMMdd hh:mm:ss SSS");

				currentKLine.setDate(myFmt.format(t.getTickDate()));

				if (isLastTick(t.getT())) {
					lastTick = true;

					for (int i = klineList.size(); i > 0; i--) {
						klineList.set(i, klineList.get(i - 1));
					}

					klineList.set(0, currentKLine);
					currentKLine.setTr(TechnicalAnalysisIndicators.getTr(currentKLine, klineList.get(1)));

					currentAtr = TechnicalAnalysisIndicators.getAtr(klineList);
					for (int i = 0; i < klineList.size(); i++) {
						stdd[i] = klineList.get(i).getTr();
					}
					currentSTD = MathUtil.getStandardDiviation(stdd);

					String writeStr = "";
					for (int i = 0; i < 101; i++) {

						JSONObject json = JSONObject.fromObject(klineList.get(i));// 将java对象转换为json对象
						String str = json.toString();
						writeStr = writeStr + str + "\r\n";

					}
					JavaFile.writefile(BASE_PATH + code + ".txt", writeStr);

					// hasPostion = false;

				}

				Thread.sleep(1);
			} catch (java.text.ParseException es) {
				es.printStackTrace();
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}

	}

	private boolean isLastTick(Double t) {
		if (t >= 0.21 || t < 0.05) {

			if (t >= 0.21) {
				if (t > currentDateList.get(currentDatePeriod)) {
					currentDatePeriod++;
					return true;
				} else {
					return false;
				}
			} else {
				if (t + 0.24 > currentDateList.get(currentDatePeriod)) {
					currentDatePeriod++;
					return true;
				} else {
					return false;
				}

			}

		} else {
			// System.out.println(t+","+currentDateList.get(currentDatePeriod));

			if (t > currentDateList.get(currentDatePeriod)) {
				currentDatePeriod++;
				return true;
			} else {
				return false;
			}
		}

	}

	private boolean closeToLastTick(Double t) {
		if (t >= 0.21 || t <= 0.08) {

			if (t >= 0.21) {
				if (t > currentDateList.get(currentDatePeriod)) {
					return true;
				} else {
					return false;
				}
			} else {
				if (t + 0.24 > currentDateList.get(currentDatePeriod)) {
					return true;
				} else {
					return false;
				}

			}

		} else {
			if (t > currentDateList.get(currentDatePeriod)) {
				return true;
			} else {
				return false;
			}
		}
	}

	private void sendStopPostion(boolean longShort) {

		if (longShort) {
			hasPostion = false;
			System.out.println("longstop");
			double pri = currentKLine.getClose();

			if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 1) {
				pri = Math.floor(pri);
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 2) {
				pri = Math.floor(pri * 0.5) * 2;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 5) {
				pri = Math.floor(pri * 0.2) * 5;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 10) {
				pri = Math.floor(pri * 0.1) * 10;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.2) {
				pri = Math.floor(pri * 5) * 0.2;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.5) {
				pri = Math.floor(pri * 2) * 0.5;
			}

			q.offer("longstop," + code + ",1," + pri + "," + pri + "\0");

		} else {
			System.out.println("short stop");
			hasShortPostion = false;
			double pri = currentKLine.getClose();

			if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 1) {
				pri = Math.floor(pri);
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 2) {
				pri = Math.floor(pri * 0.5) * 2;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 5) {
				pri = Math.floor(pri * 0.2) * 5;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 10) {
				pri = Math.floor(pri * 0.1) * 10;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.2) {
				pri = Math.floor(pri * 5) * 0.2;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.5) {
				pri = Math.floor(pri * 2) * 0.5;
			}

			q.offer("shortstop," + code + ",1," + pri + "," + pri + "\0");
		}
	}

	private void sendOrder(boolean longShort) {

		if (longShort) {
			System.out.println(code + " long sendOrder atr:" + currentAtr + " close:" + currentKLine.getClose() + " tr:"
					+ currentKLine.getTr() + " tr std:" + currentSTD);

			double pri = currentKLine.getClose();

			if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 1) {
				pri = Math.floor(pri) - 1;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 2) {
				pri = Math.floor(pri * 0.5) * 2 - 2;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 5) {
				pri = Math.floor(pri * 0.2) * 5 - 5;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 10) {
				pri = Math.floor(pri * 0.1) * 10 - 10;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.2) {
				pri = Math.floor(pri * 5) * 0.2 - 0.2;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.5) {
				pri = Math.floor(pri * 2) * 0.5 - 0.5;
			}

			if (currentDatePeriod > 0) {
				q.offer("buy," + code + ",1," + pri + "," + pri + "\0");
			}

		} else {
			System.out.println(code + " short sendOrder atr:" + currentAtr + " close:" + currentKLine.getClose()
					+ " tr:" + currentKLine.getTr() + " tr std:" + currentSTD);

			double pri = currentKLine.getClose();

			if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 1) {
				pri = Math.floor(pri) + 1;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 2) {
				pri = Math.floor(pri * 0.5) * 2 + 2;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 5) {
				pri = Math.floor(pri * 0.2) * 5 + 5;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 10) {
				pri = Math.floor(pri * 0.1) * 10 + 10;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.2) {
				pri = Math.floor(pri * 5) * 0.2 + 0.2;
			} else if (Dictionary.MinStepDictionary.get(code.replaceAll("[\\d]", "")) == 0.5) {
				pri = Math.floor(pri * 2) * 0.5 + 0.5;
			}

			if (currentDatePeriod > 0) {
				// q.offer("buy,au1905,1,2,3\0");
				q.offer("sell," + code + ",1," + pri + "," + pri + "\0");
			}
		}
	}

	public void run() {
		// TODO Auto-generated method stub
		try {
			main();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
